import Flutter
import UIKit

public class SwiftAdSuyiFlutterSdkPlugin: NSObject, FlutterPlugin {
    
    static var channel: FlutterMethodChannel?
    
    static let instance = SwiftAdSuyiFlutterSdkPlugin()
    
    public static func register(with registrar: FlutterPluginRegistrar) {
        channel = FlutterMethodChannel(name: "ad_suyi_sdk", binaryMessenger: registrar.messenger())
        registrar.addMethodCallDelegate(instance, channel: channel!)
        registrar.register(ADSuyiFlutterAdViewFactory(), withId: "ADSuyiAdView");
    }

    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        
        if(call.method == "initSdk") {
            let appId = call.arguments
            ADSuyiSDK.initWithAppId(appId as! String) { (error) in
                print("\(String(describing: error))")
            }
            result(nil)
            return
        }
        
        guard let dic: Dictionary<String, Any> = call.arguments as? Dictionary<String, Any> else {
            result(nil)
            return;
        }
        guard let adId = dic["adId"] as? Int else {
            result(nil)
            return;
        }
        switch call.method {
        case "loadSplashAd": do {
            guard let posId = dic["posId"] as? String,
                  let imgName = dic["imgName"] as? String else {
                result(nil)
                return
            }
            ADSuyiFlutterSplashAd.shared.loadAndShow(posid: posId, adId: adId, imgName: imgName)
            result(nil)
        }
        case "loadRewardAd": do {
            guard let posId = dic["posId"] as? String else {
                result(nil)
                return
            }
            ADSuyiFlutterRewardAd.shared.load(posId: posId, adId: adId)
            result(nil)
        }
        case "showRewardAd": do {
            ADSuyiFlutterRewardAd.shared.show(adId: adId)
            result(nil)
        }
        case "loadIntertitialAd": do {
            guard let posId = dic["posId"] as? String else {
                result(nil)
                return
            }
            ADSuyiFlutterIntertitialAd.shared.load(posId: posId, adId: adId)
            result(nil)
        }
        case "showIntertitialAd": do {
            ADSuyiFlutterIntertitialAd.shared.show(adId: adId)
            result(nil)
        }
        case "loadFullScreenVodAd": do {
            guard let posId = dic["posId"] as? String else {
                result(nil)
                return
            }
            ADSuyiFlutterFullScreenVodAd.shared.load(posId: posId, adId: adId)
            result(nil)
        }
        case "showFullScreenVodAd": do {
            ADSuyiFlutterFullScreenVodAd.shared.show(adId: adId)
            result(nil)
        }
        case "loadBannerAd": do {
            guard let posId = dic["posId"] as? String,
                  let adWidth = dic["adWidth"] as? Double,
                  let adHeight = dic["adHeight"] as? Double else {
                result(nil)
                return
            }
            ADSuyiFlutterBannerAd.shared.load(posId: posId, adId: adId, adWidth:adWidth, adHeight:adHeight)
            result(nil)
        }
        case "removeAd": do {
            ADSuyiFlutterAdMap.shared.deleteAd(adId: adId)
            result(nil)
        }
        case "loadNativeAd": do {
            guard let posId = dic["posId"] as? String,
                  let adWidth = dic["adWidth"] as? Double else {
                result(nil)
                return
            }
            ADSuyiFlutterNativeAd.shared.loadNativeAd(posId, adId: adId, width: CGFloat(adWidth))
        }
        default: do {
            result(nil)
        }
        }
    }
}

func getNewAdId() -> Int {
    struct Temp {
        static var adId = 0
    }
    Temp.adId -= 1;
    return Temp.adId;
}

class ADSuyiFlutterAdMap {
    static let shared = ADSuyiFlutterAdMap()
    
    var adMap = Dictionary<Int, NSObject>()
    var keyMap = Dictionary<NSObject, Int>()
    
    var nativeViewMap = Dictionary<Int,UIView>()
    var nativeViewKeyMap = Dictionary<UIView,Int>()
    
    func saveAd(ad: NSObject, adId: Int) {
        adMap[adId] = ad
        keyMap[ad] = adId
    }
    
    func readAd(adId: Int) -> NSObject? {
        return adMap[adId]
    }
    
    func readAdId(ad: NSObject) -> Int {
        return keyMap[ad] ?? -1
    }
    
    func deleteAd(adId: Int) {
        if let ad = readAd(adId: adId) {
            adMap.removeValue(forKey: adId)
            keyMap.removeValue(forKey: ad)
        }
    }
    // MARK:信息流方法
    func saveNativeView(adView:UIView, adViewId:Int) {
        nativeViewMap[adViewId] = adView
        nativeViewKeyMap[adView] = adViewId;
    }
    
    func readNativeView(adViewId:Int) -> UIView? {
        return nativeViewMap[adViewId];
    }
    
    func readNativeViewId(adView:UIView) -> Int {
        return nativeViewKeyMap[adView] ?? -1
    }
    
    func deleteNativeAdView(adViewId:Int) {
        if let adView = readNativeView(adViewId: adViewId) {
            nativeViewMap.removeValue(forKey: adViewId)
            nativeViewKeyMap.removeValue(forKey: adView)
        }
    }
    
    
}

public class ADSuyiFlutterAdView : UIView, FlutterPlatformView {
    
    var adView : UIView?
    
    public func view() -> UIView {
        return adView ?? UIView()
    }
}

public class ADSuyiFlutterAdViewFactory : NSObject, FlutterPlatformViewFactory {
    public func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
        let view = ADSuyiFlutterAdView()
        let adId = args as! Int
        view.adView = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? UIView
        return view
    }
    
    public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
        return FlutterStandardMessageCodec.sharedInstance()
    }
}

class ADSuyiFlutterSplashAd : NSObject, ADSuyiSDKSplashAdDelegate {
    
    public static let shared = ADSuyiFlutterSplashAd()
    
    func loadAndShow(posid: String, adId: Int, imgName: String) {
        var splash = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKSplashAd
        if splash == nil {
            splash = ADSuyiSDKSplashAd()
            splash!.posId = posid
            splash!.controller = getTopViewController()
            splash!.delegate = self
            splash!.backgroundColor = UIColor.adsy_get(with: UIImage(named: imgName)!, withNewSize: UIScreen.main.bounds.size)
            ADSuyiFlutterAdMap.shared.saveAd(ad: splash!, adId: adId)
        }
        if let window = getWindow() {
            splash!.loadAndShow(in: window, withBottomView: nil)
        }
    }
    
    // MARK: - ADSuyiSDKSplashAdDelegate
    
    func adsy_splashAdFail(toPresentScreen splashAd: ADSuyiSDKSplashAd, failToPresentScreen error: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId, "error" : "错误"]);
    }
    
    func adsy_splashAdClosed(_ splashAd: ADSuyiSDKSplashAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId]);
    }
    
    func adsy_splashAdSuccess(toPresentScreen splashAd: ADSuyiSDKSplashAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId]);
    }

    func adsy_splashAdClicked(_ splashAd: ADSuyiSDKSplashAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId]);
    }

    func adsy_splashAdEffective(_ splashAd: ADSuyiSDKSplashAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId]);
    }
}

class ADSuyiFlutterRewardAd : NSObject, ADSuyiSDKRewardvodAdDelegate {
    
    public static let shared = ADSuyiFlutterRewardAd()
    
    func load(posId: String, adId: Int) {
        var reward = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKRewardvodAd
        if reward == nil {
            reward = ADSuyiSDKRewardvodAd()
            reward?.posId = posId
            reward?.controller = getTopViewController()
            reward?.delegate = self
            ADSuyiFlutterAdMap.shared.saveAd(ad: reward!, adId: adId)
        }
        reward?.load()
    }
    
    func show(adId: Int) {
        if let reward = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKRewardvodAd {
            reward.show()
        }
    }
    
    func adsy_rewardvodAdLoadSuccess(_ rewardvodAd: ADSuyiSDKRewardvodAd) { }
    
    func adsy_rewardvodAdReady(toPlay rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId]);
    }
    
    func adsy_rewardvodAdVideoLoadSuccess(_ rewardvodAd: ADSuyiSDKRewardvodAd) { }
    
    func adsy_rewardvodAdWillVisible(_ rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId]);
    }
    
    func adsy_rewardvodAdDidVisible(_ rewardvodAd: ADSuyiSDKRewardvodAd) { }
    
    func adsy_rewardvodAdDidClose(_ rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId]);
    }
    
    func adsy_rewardvodAdDidClick(_ rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId]);
    }
    
    func adsy_rewardvodAdDidPlayFinish(_ rewardvodAd: ADSuyiSDKRewardvodAd) { }
    
    func adsy_rewardvodAdDidRewardEffective(_ rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onRewarded", arguments: ["adId" : adId]);
    }
    
    func adsy_rewardvodAdFail(toLoad rewardvodAd: ADSuyiSDKRewardvodAd, errorModel: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }
    
    func adsy_rewardvodAdPlaying(_ rewardvodAd: ADSuyiSDKRewardvodAd, errorModel: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }
    
}

class ADSuyiFlutterIntertitialAd : NSObject, ADSuyiSDKIntertitialAdDelegate {
    
    public static let shared = ADSuyiFlutterIntertitialAd()
    
    func load(posId: String, adId: Int) {
        var inter = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKIntertitialAd
        if inter == nil {
            inter = ADSuyiSDKIntertitialAd()
            inter?.posId = posId
            inter?.controller = getTopViewController()
            inter?.delegate = self
            ADSuyiFlutterAdMap.shared.saveAd(ad: inter!, adId: adId)
        }
        inter?.loadData()
    }
    
    func show(adId: Int) {
        if let inter = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKIntertitialAd {
            inter.show()
        }
    }
    
    func adsy_interstitialAdSucced(toLoad interstitialAd: ADSuyiSDKIntertitialAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId]);
    }
    
    func adsy_interstitialAdFailed(toLoad interstitialAd: ADSuyiSDKIntertitialAd, error: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }
    
    func adsy_interstitialAdDidPresent(_ interstitialAd: ADSuyiSDKIntertitialAd) { }
    
    func adsy_interstitialAdFailed(toPresent interstitialAd: ADSuyiSDKIntertitialAd, error: Error) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }
    
    func adsy_interstitialAdDidClick(_ interstitialAd: ADSuyiSDKIntertitialAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId]);
    }
    
    func adsy_interstitialAdDidClose(_ interstitialAd: ADSuyiSDKIntertitialAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId]);
    }
    
    func adsy_interstitialAdExposure(_ interstitialAd: ADSuyiSDKIntertitialAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId]);
    }
}

class ADSuyiFlutterFullScreenVodAd : NSObject, ADSuyiSDKFullScreenVodAdDelegate {
    
    public static let shared = ADSuyiFlutterFullScreenVodAd()
    
    func load(posId: String, adId: Int) {
        var fullScreenVodAd = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKFullScreenVodAd
        if fullScreenVodAd == nil {
            fullScreenVodAd = ADSuyiSDKFullScreenVodAd()
            fullScreenVodAd!.posId = posId
            fullScreenVodAd!.controller = getTopViewController()
            fullScreenVodAd!.delegate = self
            ADSuyiFlutterAdMap.shared.saveAd(ad: fullScreenVodAd!, adId: adId)
        }
        fullScreenVodAd!.loadData()
    }
    
    func show(adId: Int) {
        if let fullScreenVodAd = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKFullScreenVodAd {
            fullScreenVodAd.show()
        }
    }
    
    func adsy_fullScreenVodAdSucced(toLoad fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
    }
    
    func adsy_fullScreenVodAdReady(toPlay fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId]);
    }
    
    func adsy_fullScreenVodAdSuccess(toLoadVideo fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
    }
    
    func adsy_fullScreenVodAdFailed(toLoad fullScreenVodAd: ADSuyiSDKFullScreenVodAd, error: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }
    
    func adsy_fullScreenVodAdDidPresent(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
    }
    
    func adsy_fullScreenVodAdFail(toPresent fullScreenVodAd: ADSuyiSDKFullScreenVodAd, error: Error) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }
    
    func adsy_fullScreenVodAdDidClick(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId]);
    }
    
    func adsy_fullScreenVodAdDidClose(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId]);
    }
    
    func adsy_fullScreenVodAdExposure(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId]);
    }
    
    func adsy_fullScreenVodAdPlayComplete(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd, didFailed error: Error?) {
    }
    
}

class ADSuyiFlutterBannerAd: NSObject, ADSuyiSDKBannerAdViewDelegate{
    
    public static let shared = ADSuyiFlutterBannerAd()
    
    func load(posId: String, adId: Int, adWidth:Double, adHeight:Double) {
        var bannerAd = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKBannerAdView
        if bannerAd == nil {
            bannerAd = ADSuyiSDKBannerAdView.init(frame: CGRect.init(x: 0, y: 0, width: adWidth, height: adHeight))
            bannerAd!.posId = posId
            bannerAd!.controller = getTopViewController()
            bannerAd!.delegate = self
            ADSuyiFlutterAdMap.shared.saveAd(ad: bannerAd!, adId: adId)
        }
        bannerAd?.loadAndShow()
    }
    
    func adsy_bannerViewDidReceived(_ bannerView: ADSuyiSDKBannerAdView) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId]);
    }
    
    func adsy_bannerViewFail(toReceived bannerView: ADSuyiSDKBannerAdView, errorModel: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }
    
    func adsy_bannerViewClicked(_ bannerView: ADSuyiSDKBannerAdView) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId]);
    }
    
    func adsy_bannerViewClose(_ bannerView: ADSuyiSDKBannerAdView) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId]);
    }
    
    func adsy_bannerViewExposure(_ bannerView: ADSuyiSDKBannerAdView) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId]);
    }
    
}

class ADSuyiFlutterNativeAd : NSObject, ADSuyiSDKNativeAdDelegate {
    
    static let shared = ADSuyiFlutterNativeAd()

    var renderMap: NSMapTable<UIView, ADSuyiSDKNativeAd> = NSMapTable.strongToStrongObjects()

    func loadNativeAd(_ posId:String, adId:Int, width:CGFloat) {
        var loader = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKNativeAd
        if(loader == nil) {
            loader = ADSuyiSDKNativeAd.init(adSize: CGSize(width: width, height: 10))
            loader!.delegate = self
            loader!.controller = getTopViewController()
            loader!.posId = posId
            ADSuyiFlutterAdMap.shared.saveAd(ad: loader!, adId: adId)
        }
        loader!.load(1)
    }

   // MARK: - ADSuyiSDKNativeAdDelegate

    func adsy_nativeAdSucess(toLoad nativeAd: ADSuyiSDKNativeAd, adViewArray: [UIView & ADSuyiAdapterNativeAdViewDelegate]) {
        for adView in adViewArray {
            renderMap.setObject(nativeAd, forKey: adView)
            adView.adsy_registViews([adView])
        }
    }

    func adsy_nativeAdViewRenderOrRegistFail(_ adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        guard let loader = renderMap.object(forKey: adView) else {
            return;
        }
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: loader)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
        renderMap.removeObject(forKey: adView)
    }
    
    func adsy_nativeAdFail(toLoad nativeAd: ADSuyiSDKNativeAd, errorModel: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: nativeAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }

    func adsy_nativeAdViewRenderOrRegistSuccess(_ adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        guard let nativeAd = renderMap.object(forKey: adView) else {
            return;
        }
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: nativeAd)
        let adViewId = getNewAdId()
        ADSuyiFlutterAdMap.shared.saveAd(ad: adView, adId: adViewId)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onReceived", arguments: ["adId" : adId, "adViewId" : adViewId, "adHeight": adView.frame.size.height, "adWidth": adView.frame.size.width]);
        renderMap.removeObject(forKey: adView)
   }

    func adsy_nativeAdClose(_ nativeAd: ADSuyiSDKNativeAd, adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: adView)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId]);
    }

    func adsy_nativeAdClicked(_ nativeAd: ADSuyiSDKNativeAd, adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: adView)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId]);
    }

    func adsy_nativeAdExposure(_ nativeAd: ADSuyiSDKNativeAd, adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: adView)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId]);
    }

}

// MARK: Helper

func getWindow() -> UIWindow? {
    return UIApplication.shared.keyWindow;
}

func getTopViewController() -> UIViewController? {
    if let window = UIApplication.shared.keyWindow {
        return getTopViewController(from: window)
    }
    return nil
}

func getTopViewController(from window: UIWindow) -> UIViewController? {
    if let rootVc = window.rootViewController {
        return getTopViewController(from: rootVc)
    }
    return nil
}

func getTopViewController(from vc: UIViewController) -> UIViewController {
    if let newVc = vc.presentedViewController {
        return getTopViewController(from: newVc)
    }
    if let tvc = vc as? UITabBarController {
        if let newVc = tvc.selectedViewController {
            return getTopViewController(from: newVc)
        }
    }
    if let nvc = vc as? UINavigationController {
        if let newVc = nvc.topViewController {
            return getTopViewController(from: newVc)
        }
    }
    return vc
}
